package cn.com.cifi.mars.service.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cn.com.cifi.mars.bean.bo.PanoPlanCastDecisionBO;
import cn.com.cifi.mars.bean.bo.PriceValueCastDecisionEXTBO;
import cn.com.cifi.mars.bean.dto.NosTradedataDto;
import cn.com.cifi.mars.bean.dto.SysNoticeDto;
import cn.com.cifi.mars.bean.vo.price.PriceNewestVersion;
import cn.com.cifi.mars.bean.vo.price.PriceValueCompareVO;
import cn.com.cifi.mars.bean.vo.sys.rsp.SysNoticeVo;
import cn.com.cifi.mars.common.exception.MsgException;
import cn.com.cifi.mars.constant.CodeEnum;
import cn.com.cifi.mars.constant.Constants;
import cn.com.cifi.mars.constant.IsDeleteEnum;
import cn.com.cifi.mars.constant.ModuleTypeEunm;
import cn.com.cifi.mars.constant.NoticeAffectedEnum;
import cn.com.cifi.mars.constant.NumberEnum;
import cn.com.cifi.mars.constant.OrgTypeEunm;
import cn.com.cifi.mars.constant.ProcessingModeEnum;
import cn.com.cifi.mars.constant.ProcessingStateEnum;
import cn.com.cifi.mars.constant.VersionCreateEnum;
import cn.com.cifi.mars.constant.VersionStatusEnum;
import cn.com.cifi.mars.constant.VersionTypeEunm;
import cn.com.cifi.mars.entity.PanoplanBuildPlan;
import cn.com.cifi.mars.entity.PanoplanBuildPlanItem;
import cn.com.cifi.mars.entity.PriceValueOrg;
import cn.com.cifi.mars.entity.PriceVersion;
import cn.com.cifi.mars.entity.SysNotice;
import cn.com.cifi.mars.entity.common.IdmUser;
import cn.com.cifi.mars.mapper.mars.PanoplanBuildPlanMapper;
import cn.com.cifi.mars.mapper.mars.PriceValueOrgMapper;
import cn.com.cifi.mars.mapper.mars.PriceVersionMapper;
import cn.com.cifi.mars.mapper.mars.StageMapper;
import cn.com.cifi.mars.mapper.mars.SysNoticeMapper;
import cn.com.cifi.mars.service.DmOdsNosTradedataviewformarsService;
import cn.com.cifi.mars.service.PanoplanBuildPlanService;
import cn.com.cifi.mars.service.PriceValueOrgService;
import cn.com.cifi.mars.service.PriceVersionValueOrgService;
import cn.com.cifi.mars.service.SignPlanVersionService;
import cn.com.cifi.mars.service.SupplyPlanVersionService;
import cn.com.cifi.mars.service.SysNoticeService;
import cn.com.cifi.mars.service.VsNosTradedataviewformarsService;
import cn.com.cifi.mars.util.UUIDUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yyd
 * @since 2019-10-16
 */
@Service
@Slf4j
public class SysNoticeServiceImpl extends ServiceImpl<SysNoticeMapper, SysNotice> implements SysNoticeService {

	@Autowired
	private SysNoticeMapper sysNoticeMapper;

	@Autowired
	private PriceVersionMapper priceVersionMapper;

	@Autowired
	private PriceValueOrgMapper priceValueOrgMapper;

	@Autowired
	private PanoplanBuildPlanMapper panoplanBuildPlanMapper;

	@Autowired
	private PriceVersionValueOrgService priceVersionValueOrgService;

	@Autowired
	private PriceValueOrgService priceValueOrgService;

	@Autowired
	private PriceVersionValueOrgServiceImpl priceVersionValueOrgServiceImpl;

	@Autowired
	private VsNosTradedataviewformarsService vsNosTradedataviewformarsService;

	@Autowired
	private StageMapper stageMapper;

	@Autowired
	private SupplyPlanVersionService supplyPlanVersionService;

	@Autowired
	private MymRoomInfoServiceImpl mymRoomInfoServiceImpl;

	@Autowired
	private SignPlanVersionService signPlanVersionService;

	@Autowired
	private DmOdsNosTradedataviewformarsService dmOdsNosTradedataviewformarsService;

	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private PriceVersionServiceImpl priceVersionServiceImpl;

	@Autowired
	private PanoplanBuildPlanService panoplanBuildPlanService;

	//如果他的产品构成是车位 那么这里就是车位
	static List<String> isParkList = Arrays.asList("139","140","141","142","154");
	
	/**
	 * 分页查询系统待办
	 */
	@Override
	public SysNoticeVo getSysNoticePage(String current, String pageSize) {
		SysNoticeVo vo=new SysNoticeVo();
		Page<SysNoticeDto>pageDto=new Page<>();
		//参数当前页
		pageDto.setCurrent(Integer.parseInt(current));
		//参数每页数量
		pageDto.setSize(Integer.parseInt(pageSize));
		List<SysNoticeDto>list=sysNoticeMapper.selectSysNoticePage(pageDto,IsDeleteEnum.NO.getKey()+"");
		list.forEach(x->{
			//处理状态 0.未处理 1.已处理(手动处理、自动处理、程序自动执行，后变成已处理)
			String state=x.getState();
			if(state.equals(ProcessingStateEnum.UNTREATED.getKey())) {
				x.setState(ProcessingStateEnum.UNTREATED.getValue());
			}else if(state.equals(ProcessingStateEnum.PROCESSED.getKey())) {
				x.setState(ProcessingStateEnum.PROCESSED.getValue());
			}
			//任务类型(1. 面积变更 2.楼栋计划 3. 定价 4.调价 )
			String taskType=x.getTaskType();
			if(taskType.equals(NoticeAffectedEnum.AREA_CHANGE.getKey())) {
				x.setTaskType(NoticeAffectedEnum.AREA_CHANGE.getValue());
			}else if(taskType.equals(NoticeAffectedEnum.PANO_CHANGE.getKey())) {
				x.setTaskType(NoticeAffectedEnum.PANO_CHANGE.getValue());
			}else if(taskType.equals(NoticeAffectedEnum.MY_CHANGE.getKey())) {
				x.setTaskType(NoticeAffectedEnum.MY_CHANGE.getValue());
			}else if(taskType.equals(NoticeAffectedEnum.NOS_CHANGE.getKey())) {
				x.setTaskType(NoticeAffectedEnum.NOS_CHANGE.getValue());
			}
			
			//受影响版本阶段(0.动态版 1.投资版)对应字典表
			String affectedVersionStage=x.getAffectedVersionStage();
			if(affectedVersionStage.equals(VersionTypeEunm.INVESTMENT.getKey())) {
				x.setAffectedVersionStage(VersionTypeEunm.INVESTMENT.getValue());
			}else if(affectedVersionStage.equals(VersionTypeEunm.DYNAMIC.getKey())) {
				x.setAffectedVersionStage(VersionTypeEunm.DYNAMIC.getValue());
			}
			//处理方式(1.手动：手动调价按钮 2.自动：自动调价按钮 3.系统：程序自动刷新 4.手动+自动)
			String processingMode=x.getProcessingMode();
			if(processingMode.equals(ProcessingModeEnum.MANUAL.getKey())) {
				x.setProcessingMode(ProcessingModeEnum.MANUAL.getValue());
			}else if(processingMode.equals(ProcessingModeEnum.AUTOMATIC.getKey())) {
				x.setProcessingMode(ProcessingModeEnum.AUTOMATIC.getValue());
			}else if(processingMode.equals(ProcessingModeEnum.SYSTEM.getKey())) {
				x.setProcessingMode(ProcessingModeEnum.SYSTEM.getValue());
			}else if(processingMode.equals(ProcessingModeEnum.MANUAL_AUTOMATION.getKey())) {
				x.setProcessingMode(ProcessingModeEnum.MANUAL_AUTOMATION.getValue());
			}
		});
		vo.setCurrent(pageDto.getCurrent());
		vo.setPages(pageDto.getPages());
		vo.setPageSize(pageDto.getSize());
		vo.setTotal(pageDto.getTotal());
		vo.setList(list);
		return vo;
	}

	/**
	 * 手动调价->动态版
	 * id:系统待办Id
	 */
	@Override
	public PriceNewestVersion updateManualPrice(String noticeId, IdmUser idmUser) {
		SysNotice sysNotice = sysNoticeMapper.selectById(noticeId);
		String state=sysNotice.getState();
		if(state.equals(ProcessingStateEnum.PROCESSED.getKey())) {
			//当前消息已处理,无需再进行处理
			throw new MsgException(CodeEnum.SYS_NOTICE_MSG_ERROR);
		}

		//受影响版本阶段(0.动态版 1.投资版)对应字典表
		String taskType = sysNotice.getTaskType();
		String projectFid = sysNotice.getStagesId();
		String versionId = "";

		//是货值的代办信息
		if(taskType.equals(ModuleTypeEunm.PRICE.getKey())){
			//查看代办来源
			String taskSource = sysNotice.getTaskSource();
			if(!taskSource.equals(VersionTypeEunm.INVESTMENT.getKey())){
				versionId = priceValueOrgService.updateDynamicOrgValue(sysNotice, idmUser);
			}else{
				String key = Constants.PRICE_CREATE_VERSION_LOCK + VersionTypeEunm.INVESTMENT.getKey()+ "_" + projectFid;
				if (!redisTemplate.opsForValue().setIfAbsent(key, 1, 180, TimeUnit.SECONDS)) {
					throw new MsgException(CodeEnum.SYS_EXISTENT);
				}
				try {
					versionId = priceVersionValueOrgService.createSysCastDecisionVersion(projectFid, VersionCreateEnum.MANUALCREATE.getKey(), idmUser, 2, null);
				}finally {
					redisTemplate.delete(key);
				}
			}
		}

		PriceNewestVersion priceNewestVersion = new PriceNewestVersion();
		//查询货值版本信息
		if (StringUtils.isNotEmpty(versionId)) {
			PriceVersion priceVersion = priceVersionMapper.selectByPrimaryKey(versionId);
			if(priceVersion != null){
				priceNewestVersion.setVersionId(priceVersion.getId());
				priceNewestVersion.setVersionType(priceVersion.getVersionType());
			}
		}

		return priceNewestVersion;
	}

	@Override
	public SysNotice selectById(String noticeId) {
		return sysNoticeMapper.selectById(noticeId);
	}

	/**
	 * 根据id获取楼栋计划信息
	 * @param id
	 * @return
	 */
	public PanoplanBuildPlan getPanoplanBuildPlan(String id) {
		PanoplanBuildPlan bean=panoplanBuildPlanMapper.selectByPrimaryKey(id, IsDeleteEnum.NO.getKey()+"");
		if(bean==null) {
			throw new MsgException(CodeEnum.NON_PANOPLANBUILDPLAN_ERROR);
		}
		return bean;
	}
	
	/**
	 * 根据分期id 获取最新的待办Id
	 */
	@Override
	public List<SysNotice> getNoticeId(String stagesId) {
		List<SysNotice> notices = sysNoticeMapper.selectByStagesIdAndState(stagesId, ModuleTypeEunm.PRICE.getKey(), ProcessingStateEnum.UNTREATED.getKey(), IsDeleteEnum.NO.getKey());

		List<SysNotice> resultNotices = null;
		if (CollectionUtils.isNotEmpty(notices)){
			resultNotices = new ArrayList<SysNotice>();
			for (SysNotice notice : notices){
				notice.setTaskName(notice.getDescInfo());

				resultNotices.add(notice);
			}
		}
		return resultNotices;
	}
	
    /**
     * 拉取昨天nos系统签约数据
     */
    @Override
    public String syncNos() {
	    LocalDateTime now = LocalDateTime.now();
	    String checkTime = now.minusDays(1).toLocalDate().toString();
	    List<NosTradedataDto> nosList = vsNosTradedataviewformarsService.queryByDate(checkTime);
	    try {
		    dmOdsNosTradedataviewformarsService.syncNosContact();
	    }catch (Exception e){
		    log.error("#########  NOS 全量拉取签约数据接口 错误信息："+e.getMessage(), e);
	    }

	    try{
		    //归属年月
		    LocalDate ascriptionDate = LocalDate.now();
		    int day = now.getDayOfMonth();
		    int hour = now.getHour();
		    if (day == Constants.ONE && hour <=  Constants.SIX){//一号
			    ascriptionDate = ascriptionDate.minusMonths(1);
		    }
		    //NOS查询数据去重
		    Set<String> stagetCodeLists = Optional.of(nosList).orElseGet(ArrayList::new)
				    .stream().map(NosTradedataDto::getStageCode)
				    .collect(Collectors.toSet());

		    if(CollectionUtils.isNotEmpty(stagetCodeLists)){
			    for (String stageCode : stagetCodeLists) {
				    String stageId = stageMapper.selectByStageCode(stageCode);
				    PriceVersion priceVersion = priceVersionServiceImpl.getNewestPriceVersionAllVersionState(stageId);
				    if (priceVersion != null) {
					    String versionType = priceVersion.getVersionType();
						String versionState = priceVersion.getVersionState();
						if (versionType.equals(VersionTypeEunm.DYNAMIC.getKey())){
						    if (versionState.equals(VersionStatusEnum.NOTPREPARED.getKey()) || versionState.equals(VersionStatusEnum.ORGANIZATION.getKey())
								    || versionState.equals(VersionStatusEnum.EXAMINEDAPPROVED.getKey()) || versionState.equals(VersionStatusEnum.FAILUREAPPROVED.getKey())){
							   
						    	priceVersionValueOrgService.priceRefreshActualValueInfo(stageId, priceVersion, null, null,LocalDateTime.now(), Constants.MY , null);
						    }else if (versionState.equals(VersionStatusEnum.SUCCESSAPPROVED.getKey())){
							    try {
								    String versionId = priceVersionValueOrgService.createSysAppointDynamicVersion(priceVersion.getProjectfId(), priceVersion, null, ascriptionDate, "实际数据刷新生成", 3, null, Constants.NOS);

								    mymRoomInfoServiceImpl.noticeDownsRecordProcessedInfo("NOS房间变动-生成版本", checkTime, versionId, priceVersion.getProjectId(), priceVersion.getProjectfId(), ProcessingStateEnum.PROCESSED.getKey(), ProcessingModeEnum.SYSTEM.getKey(), "nos", now);

								    supplyPlanVersionService.createSupplyPlanVersion(versionId, VersionTypeEunm.DYNAMIC.getKey(), Constants.SYS);
							    } catch (Exception e) {
								    log.error("###################     syncNos    SUCCESSAPPROVED   货值自动生成:"+e.getMessage(), e);
							    }
						    }else if (versionState.equals(VersionStatusEnum.SYSGENERATION.getKey())){
							    //查看货值版本是否有被供货确认使用
							    boolean isComfirm = supplyPlanVersionService.supplyIsComfirm(priceVersion.getId());
							    if (isComfirm){
								    try {
									    String versionId = priceVersionValueOrgService.createSysAppointDynamicVersion(priceVersion.getProjectfId(), priceVersion, null, ascriptionDate, "实际数据刷新生成", 3, null, Constants.NOS);

									    supplyPlanVersionService.createSupplyPlanVersion(versionId, VersionTypeEunm.DYNAMIC.getKey(), Constants.SYS);
								    } catch (Exception e) {
									    log.error("###################    syncNos  货值自动生成:"+e.getMessage(), e);
								    }
							    }else{
								    //查看货值版本是否有被签约使用
								    Map<String, Boolean> signMap = signPlanVersionService.priceBoolean(Arrays.asList(priceVersion.getId()));
								    Boolean isSign = signMap.get(priceVersion.getId());
								    if (isSign){
									    try {
										    String versionId = priceVersionValueOrgService.createSysAppointDynamicVersion(priceVersion.getProjectfId(), priceVersion, null, ascriptionDate, "实际数据刷新生成", 3, null, Constants.NOS);

										    supplyPlanVersionService.createSupplyPlanVersion(versionId, VersionTypeEunm.DYNAMIC.getKey(), Constants.SYS);
									    } catch (Exception e) {
										    log.error("###################    syncNos   货值自动生成:"+e.getMessage(), e);
									    }
								    }else{
									    //查看货值版本是否有定稿
									    Integer isFinalization = priceVersion.getIsFinalization();

									    if (isFinalization != null && isFinalization.equals(IsDeleteEnum.YES.getKey())){
										    try {
											    String versionId = priceVersionValueOrgService.createSysAppointDynamicVersion(priceVersion.getProjectfId(), priceVersion, null, ascriptionDate, "实际数据刷新生成", 3, null, Constants.NOS);

											    supplyPlanVersionService.createSupplyPlanVersion(versionId, VersionTypeEunm.DYNAMIC.getKey(), Constants.SYS);
										    } catch (Exception e) {
											    log.error("###################    syncNos   货值自动生成:"+e.getMessage(), e);
										    }
									    }else{
										    Map<String, String> resultVersionIdAndVersionTypeMap = new HashMap<String, String>();
										    try{
											    resultVersionIdAndVersionTypeMap = priceVersionValueOrgService.priceRefreshActualValueInfo(stageId, priceVersion, null, null,LocalDateTime.now(), Constants.NOS , null);
										    }catch (Exception e){
											    log.error("###################    syncNos    货值自动生成:"+e.getMessage(), e);
										    }

										    if (CollectionUtils.isNotEmpty(resultVersionIdAndVersionTypeMap)){
											    for (Map.Entry<String, String> resultmap : resultVersionIdAndVersionTypeMap.entrySet()){
												    try {
													    supplyPlanVersionService.createSupplyPlanVersion(resultmap.getKey(), resultmap.getValue(), Constants.SYS);
												    }catch (Exception e){
													    log.error("###################     syncNos    供货自动生成刷新:"+e.getMessage(), e);
												    }
											    }
										    }
									    }
								    }
							    }
						    }else if (versionState.equals(VersionStatusEnum.APPROVED.getKey())){
							    //修改添加代办消息
							    try{
								    mymRoomInfoServiceImpl.noticeDownsRecordProcessedInfo(Constants.NOTICE_NOS_DELAY, checkTime, priceVersion.getId(), priceVersion.getProjectId(), priceVersion.getProjectfId(), ProcessingStateEnum.UNTREATED.getKey(), ProcessingModeEnum.SYSTEM_DELAY.getKey(), Constants.NOS, now);
							    }catch (Exception e){
								    log.error("################    syncNos   添加代办消息   error :"+e.getMessage(), e);
							    }
						    }
					    }else{
						    if (!versionType.equals(VersionTypeEunm.INVESTMENT.getKey())){
						    	if (versionState.equals(VersionStatusEnum.SUCCESSAPPROVED.getKey())){
									try {
										String versionId = priceVersionValueOrgService.createSysAppointDynamicVersion(priceVersion.getProjectfId(), priceVersion, null, ascriptionDate, "实际数据刷新生成", 3, null, Constants.NOS);

										supplyPlanVersionService.createSupplyPlanVersion(versionId, VersionTypeEunm.DYNAMIC.getKey(), Constants.SYS);
									} catch (Exception e) {
										log.error("###################     syncNos    货值自动生成:"+e.getMessage(), e);
									}
								}else{
									//修改添加代办消息
									try{
										mymRoomInfoServiceImpl.noticeDownsRecordProcessedInfo(Constants.NOTICE_NOS_DELAY, checkTime, priceVersion.getId(), priceVersion.getProjectId(), priceVersion.getProjectfId(), ProcessingStateEnum.UNTREATED.getKey(), ProcessingModeEnum.SYSTEM_DELAY.getKey(), Constants.NOS, now);
									}catch (Exception e){
										log.error("################    syncNos   添加代办消息   error :"+e.getMessage(), e);
									}
								}
						    }
					    }
				    }
			    }
		    }
	    }catch (Exception e){
		    log.error("#########  NOS 货值变动错误信息："+e.getMessage(), e);
	    }

	    return null;
    }

	@Override
	public List<SysNotice> selectModeByProjectFidAndVersionType(String projectFid, String noticeType, String versionType, String noticeState, int isDel){
		return sysNoticeMapper.selectModeByProjectFidAndVersionType(projectFid, noticeType, versionType, noticeState, isDel);
	}

	@Override
	public List<PriceValueCompareVO> panoCastDecisionVersionChange(String projectFid) {

		List<PriceValueCompareVO> compareVOList = new ArrayList<PriceValueCompareVO>();

		//获取最新的投资版楼栋计划
		PanoPlanCastDecisionBO panoPlanCastDecisionBO = panoplanBuildPlanService.selectNewestByFid(projectFid, Arrays.asList(VersionTypeEunm.INVESTMENT.getValue()), IsDeleteEnum.NO.getKey());

		List<PriceValueCompareVO> compareProductVOList = new ArrayList<PriceValueCompareVO>();
		//获取最新的投资版货值信息
		PriceVersion priceVersion = priceVersionMapper.selectNewestByProjectFidAndType(projectFid, VersionTypeEunm.INVESTMENT.getKey(), IsDeleteEnum.NO.getKey());
		if (priceVersion != null){

			//产品构成
			Map<String, PriceValueCastDecisionEXTBO> valueProduceMap = new HashMap<String, PriceValueCastDecisionEXTBO>();
			List<PriceValueCastDecisionEXTBO> productOrgs = priceValueOrgMapper.selectProductByVersionId(priceVersion.getId(), OrgTypeEunm.ORG_PRODUCT.getKey(), IsDeleteEnum.NO.getKey());
			for (PriceValueCastDecisionEXTBO productOrg : productOrgs){
				String code = productOrg.getGroupId()+"&"+productOrg.getBatchCode()+"&"+productOrg.getProductCode()+"&"+productOrg.getFreeTypeName()+"&"+productOrg.getBusinessTypeName()+"&"+productOrg.getProTypeName();
				valueProduceMap.put(code ,productOrg);
			}

			List<PanoplanBuildPlanItem> panoPproductItems = panoPlanCastDecisionBO.getProductItems();
			for (PanoplanBuildPlanItem panoPproductItem : panoPproductItems){

				String code = panoPproductItem.getBatchId()+"&"+panoPproductItem.getBatchNum()+"&"+panoPproductItem.getProductTypeNum()+"&"+panoPproductItem.getDecorateName()+"&"+panoPproductItem.getSaleType()+"&"+panoPproductItem.getProType();

				PriceValueCompareVO compareVO = new PriceValueCompareVO();
				compareVO.setId(UUIDUtils.create());
				compareVO.setCode(panoPproductItem.getBatchId() + "&" + panoPproductItem.getBatchNum());
				compareVO.setName(panoPproductItem.getProductTypeName());
				compareVO.setType(OrgTypeEunm.ORG_PRODUCT.getKey());
				if (isParkList.contains(panoPproductItem.getProductTypeNum())){
					compareVO.setIsParking(IsDeleteEnum.YES.getKey());
				}else{
					compareVO.setIsParking(IsDeleteEnum.NO.getKey());
				}

				//开始对比
				PriceValueCastDecisionEXTBO valueOrg = valueProduceMap.get(code);
				if (valueOrg != null){

					if(!panoPproductItem.getBatchRoomNum().equals(valueOrg.getNum())){
						Integer subNum = (panoPproductItem.getBatchRoomNum()==null?0:panoPproductItem.getBatchRoomNum()) - (valueOrg.getNum()==null?0:valueOrg.getNum());

						List<PriceValueCompareVO.PriceValueCompareDetailVO> detailList = compareVO.getDetailList();
						if(CollectionUtils.isEmpty(detailList)){
							detailList = new ArrayList<PriceValueCompareVO.PriceValueCompareDetailVO>();
						}
						PriceValueCompareVO.PriceValueCompareDetailVO detailVO = new PriceValueCompareVO.PriceValueCompareDetailVO();
						detailVO.setChangeType(Constants.NUM_CHANGE);
						if(subNum > 0){
							detailVO.setChangeDetail(Constants.ADD_NUM_CHANGE+Math.abs(subNum));
						}else{
							detailVO.setChangeDetail(Constants.REDUCE_NUM_CHANGE+Math.abs(subNum));
						}
						detailList.add(detailVO);

						compareVO.setDetailList(detailList);
					}

					if (!isParkList.contains(panoPproductItem.getProductTypeNum())) {
						if (!panoPproductItem.getBatchSaleArea().equals(valueOrg.getSaleArea())) {
							BigDecimal extArea = panoPproductItem.getBatchSaleArea() == null ? new BigDecimal(0) : panoPproductItem.getBatchSaleArea();
							BigDecimal orgArea = valueOrg.getSaleArea() == null ? new BigDecimal(0) : valueOrg.getSaleArea();
							BigDecimal subArea = extArea.subtract(orgArea).setScale(4, BigDecimal.ROUND_HALF_UP);

							List<PriceValueCompareVO.PriceValueCompareDetailVO> detailList = compareVO.getDetailList();
							if (CollectionUtils.isEmpty(detailList)) {
								detailList = new ArrayList<PriceValueCompareVO.PriceValueCompareDetailVO>();
							}
							PriceValueCompareVO.PriceValueCompareDetailVO detailVO = new PriceValueCompareVO.PriceValueCompareDetailVO();
							detailVO.setChangeType(Constants.AREA_CHANGE);
							if (subArea.compareTo(new BigDecimal(0)) > 0) {
								detailVO.setChangeDetail(Constants.ADD_AREA_CHANGE + subArea.abs());
							} else {
								detailVO.setChangeDetail(Constants.REDUCE_AREA_CHANGE + subArea.abs());
							}
							detailList.add(detailVO);

							compareVO.setDetailList(detailList);
						}
					}

					List<PriceValueCompareVO.PriceValueCompareDetailVO> detailList = compareVO.getDetailList();
					if(CollectionUtils.isNotEmpty(detailList)){

						compareVO.setChangeBeforeNum(valueOrg.getNum());
						compareVO.setChangeAfterNum(panoPproductItem.getBatchRoomNum());

						if (!isParkList.contains(panoPproductItem.getProductTypeNum())){
							compareVO.setChangeBeforeArea(valueOrg.getSaleArea());
							compareVO.setChangeAfterArea(panoPproductItem.getBatchSaleArea());
						}

						compareProductVOList.add(compareVO);
					}
				}else{
					List<PriceValueCompareVO.PriceValueCompareDetailVO> detailList = compareVO.getDetailList();
					if(CollectionUtils.isEmpty(detailList)){
						detailList = new ArrayList<PriceValueCompareVO.PriceValueCompareDetailVO>();
					}
					PriceValueCompareVO.PriceValueCompareDetailVO detailVO = new PriceValueCompareVO.PriceValueCompareDetailVO();
					detailVO.setChangeType(Constants.ADD_PRODUCT_TYPE);
					detailVO.setChangeDetail(Constants.ADD_PRODUCT_DETAIL+panoPproductItem.getProductTypeName());
					detailList.add(detailVO);
					compareVO.setDetailList(detailList);

					compareVO.setChangeAfterNum(panoPproductItem.getBatchRoomNum());
					if (!isParkList.contains(panoPproductItem.getProductTypeNum())) {
						compareVO.setChangeAfterArea(panoPproductItem.getBatchSaleArea());
					}

					compareProductVOList.add(compareVO);
				}

				valueProduceMap.remove(code);
			}

			if(CollectionUtils.isNotEmpty(valueProduceMap)){
				for (Map.Entry<String, PriceValueCastDecisionEXTBO> orgMap :valueProduceMap.entrySet()){
					PriceValueCastDecisionEXTBO org = orgMap.getValue();

					PriceValueCompareVO compareVO = new PriceValueCompareVO();
					compareVO.setId(UUIDUtils.create());
					compareVO.setCode(org.getGroupId()+"&"+org.getBatchCode());
					compareVO.setType(OrgTypeEunm.ORG_PRODUCT.getKey());
					compareVO.setName(org.getProductType());

					compareVO.setChangeBeforeNum(org.getNum());
					if (isParkList.contains(org.getProductCode())){
						compareVO.setIsParking(IsDeleteEnum.YES.getKey());
					}else{
						compareVO.setIsParking(IsDeleteEnum.NO.getKey());
						compareVO.setChangeBeforeArea(org.getSaleArea());
					}

					List<PriceValueCompareVO.PriceValueCompareDetailVO> detailList = compareVO.getDetailList();
					if(CollectionUtils.isEmpty(detailList)){
						detailList = new ArrayList<PriceValueCompareVO.PriceValueCompareDetailVO>();
					}
					PriceValueCompareVO.PriceValueCompareDetailVO detailVO = new PriceValueCompareVO.PriceValueCompareDetailVO();
					detailVO.setChangeType(Constants.DELETE_PRODUCT_TYPE);
					detailVO.setChangeDetail(Constants.DELETE_PRODUCT_DETAIL);
					detailList.add(detailVO);
					compareVO.setDetailList(detailList);

					compareProductVOList.add(compareVO);
				}
			}

			if (CollectionUtils.isNotEmpty(compareProductVOList)){
				//批次
				Map<String, PriceValueCastDecisionEXTBO> valueBatchMap = new HashMap<String, PriceValueCastDecisionEXTBO>();
				List<PriceValueCastDecisionEXTBO> batchOrgs = priceValueOrgMapper.selectBatchByVersionId(priceVersion.getId(), OrgTypeEunm.ORG_BATCH.getKey(), IsDeleteEnum.NO.getKey());
				for (PriceValueCastDecisionEXTBO batchOrg : batchOrgs){
					String code = batchOrg.getGroupId()+"&"+batchOrg.getOrgCode();
					valueBatchMap.put(code ,batchOrg);
				}

				Map<String, PanoplanBuildPlanItem> panoBatchMap = new HashMap<String, PanoplanBuildPlanItem>();
				List<PanoplanBuildPlanItem> batchItems = panoPlanCastDecisionBO.getBatchItems();
				for (PanoplanBuildPlanItem batchItem : batchItems){
					String code = batchItem.getBatchId()+"&"+batchItem.getBatchNum();
					panoBatchMap.put(code, batchItem);
				}

				Map<String, PriceValueCompareVO> batchCompareMap = new HashMap<String, PriceValueCompareVO>();
				for (PriceValueCompareVO productCompareVO : compareProductVOList){

					String code = productCompareVO.getCode();
					PriceValueCastDecisionEXTBO valueBatch = valueBatchMap.get(code);
					PanoplanBuildPlanItem panoBatch = panoBatchMap.get(code);

					PriceValueCompareVO compareVO = batchCompareMap.get(code);
					if (compareVO == null){
						compareVO = new PriceValueCompareVO();
						String batchCompareId = UUIDUtils.create();
						compareVO.setId(batchCompareId);
						compareVO.setType(OrgTypeEunm.ORG_BATCH.getKey());
					}

					if (panoBatch != null){
						compareVO.setCode(panoBatch.getBatchId());
					}else{
						compareVO.setCode(valueBatch.getGroupId());
					}

					productCompareVO.setPid(compareVO.getId());
					compareVOList.add(productCompareVO);

					List<PriceValueCompareVO.PriceValueCompareDetailVO> detailList = compareVO.getDetailList();
					if (CollectionUtils.isEmpty(detailList)) {
						detailList = new ArrayList<PriceValueCompareVO.PriceValueCompareDetailVO>();
					}
					PriceValueCompareVO.PriceValueCompareDetailVO detailVO = new PriceValueCompareVO.PriceValueCompareDetailVO();

					if (valueBatch != null) {
						compareVO.setName(valueBatch.getOrgName());
						detailVO.setChangeDetail(Constants.UPDATE_BATCH_DETAIL + valueBatch.getOrgName());
					} else {
						compareVO.setName(NumberEnum.getValueByKey(panoBatch.getBatchNum()) + "批次");
						detailVO.setChangeDetail(Constants.UPDATE_BATCH_DETAIL + NumberEnum.getValueByKey(panoBatch.getBatchNum()) + "批次");
					}
					detailVO.setChangeType(Constants.UPDATE_BATCH_TYPE);
					detailList.add(detailVO);
					compareVO.setDetailList(detailList);

					compareVO.setChangeBeforeNum(productCompareVO.getChangeBeforeNum() == null ? 0 : productCompareVO.getChangeBeforeNum());
					compareVO.setChangeBeforeArea(productCompareVO.getChangeBeforeArea() == null ? new BigDecimal(0) : productCompareVO.getChangeBeforeArea());
					compareVO.setChangeAfterNum(productCompareVO.getChangeAfterNum() == null ? 0 : productCompareVO.getChangeAfterNum());
					compareVO.setChangeAfterArea(productCompareVO.getChangeAfterArea() == null ? new BigDecimal(0) : productCompareVO.getChangeAfterArea());

					batchCompareMap.put(code, compareVO);
				}

				//组团
				Map<String, PriceValueOrg> valueGroupMap = new HashMap();
				QueryWrapper<PriceValueOrg> groupWrapper = new QueryWrapper<PriceValueOrg>();
				groupWrapper.eq("version_id", priceVersion.getId())
						.eq("type", OrgTypeEunm.ORG_GROUP.getKey())
						.eq("is_delete", IsDeleteEnum.NO.getKey());
				List<PriceValueOrg> groupOrg = priceValueOrgMapper.selectList(groupWrapper);
				for (PriceValueOrg org : groupOrg){
					valueGroupMap.put(org.getOrgId(), org);
				}

				Map<String, PanoplanBuildPlanItem> panoGroupMap = new HashMap();
				List<PanoplanBuildPlanItem> groupItems = panoPlanCastDecisionBO.getGroupItems();
				for (PanoplanBuildPlanItem groupItem : groupItems){
					panoGroupMap.put(groupItem.getBatchId(), groupItem);
				}

				Map<String, PriceValueCompareVO> groupCompareMap = new HashMap<String, PriceValueCompareVO>();
				for (Map.Entry<String, PriceValueCompareVO> batchComparemap : batchCompareMap.entrySet()){
					PriceValueCompareVO batchCompare = batchComparemap.getValue();

					String code = batchCompare.getCode();
					PriceValueCastDecisionEXTBO valueGroup = valueBatchMap.get(code);
					PanoplanBuildPlanItem panoGroup = panoBatchMap.get(code);

					PriceValueCompareVO compareVO = groupCompareMap.get(code);
					if (compareVO == null){
						compareVO = new PriceValueCompareVO();
						String grouopCompareId = UUIDUtils.create();
						compareVO.setId(grouopCompareId);
						compareVO.setType(OrgTypeEunm.ORG_GROUP.getKey());
					}

					batchCompare.setPid(compareVO.getId());
					compareVOList.add(batchCompare);

					List<PriceValueCompareVO.PriceValueCompareDetailVO> detailList = compareVO.getDetailList();
					if (CollectionUtils.isEmpty(detailList)) {
						detailList = new ArrayList<PriceValueCompareVO.PriceValueCompareDetailVO>();
					}
					PriceValueCompareVO.PriceValueCompareDetailVO detailVO = new PriceValueCompareVO.PriceValueCompareDetailVO();

					if (valueGroup != null) {
						compareVO.setName(valueGroup.getOrgName());
						detailVO.setChangeDetail(Constants.UPDATE_GROUP_DETAIL + valueGroup.getOrgName());
					} else {
						compareVO.setName(panoGroup.getBatchName());
						detailVO.setChangeDetail(Constants.UPDATE_GROUP_DETAIL + panoGroup.getBatchName());
					}
					detailVO.setChangeType(Constants.UPDATE_GROUP_TYPE);
					detailList.add(detailVO);
					compareVO.setDetailList(detailList);

					compareVO.setChangeBeforeNum(batchCompare.getChangeBeforeNum() == null ? 0 : batchCompare.getChangeBeforeNum());
					compareVO.setChangeBeforeArea(batchCompare.getChangeBeforeArea() == null ? new BigDecimal(0) : batchCompare.getChangeBeforeArea());
					compareVO.setChangeAfterNum(batchCompare.getChangeAfterNum() == null ? 0 : batchCompare.getChangeAfterNum());
					compareVO.setChangeAfterArea(batchCompare.getChangeAfterArea() == null ? new BigDecimal(0) : batchCompare.getChangeAfterArea());

					batchCompareMap.put(code, compareVO);
				}

				//分期
				QueryWrapper<PriceValueOrg> projectFWrapper = new QueryWrapper<PriceValueOrg>();
				projectFWrapper.eq("version_id", priceVersion.getId())
						.eq("type", OrgTypeEunm.ORG_STAGE.getKey())
						.eq("is_delete", IsDeleteEnum.NO.getKey());
				PriceValueOrg projectFOrg = priceValueOrgMapper.selectOne(projectFWrapper);
				PriceValueCompareVO projectCompareVO = new PriceValueCompareVO();
				String projectFCompareId = UUIDUtils.create();
				projectCompareVO.setId(projectFCompareId);
				projectCompareVO.setPid("0");
				projectCompareVO.setName(projectFOrg.getOrgName());
				projectCompareVO.setType(OrgTypeEunm.ORG_STAGE.getKey());

				for (Map.Entry<String, PriceValueCompareVO> groupComparemap : groupCompareMap.entrySet()){
					PriceValueCompareVO groupCompare = groupComparemap.getValue();

					groupCompare.setPid(projectFCompareId);
					compareVOList.add(groupCompare);

					projectCompareVO.setChangeBeforeNum((projectCompareVO.getChangeBeforeNum() == null ? 0 : projectCompareVO.getChangeBeforeNum()) + (groupCompare.getChangeBeforeNum() == null ? 0 : groupCompare.getChangeBeforeNum()));
					projectCompareVO.setChangeBeforeArea(priceVersionValueOrgServiceImpl.BigDecimalADD(projectCompareVO.getChangeAfterArea(), groupCompare.getChangeAfterArea()));
					projectCompareVO.setChangeAfterNum((projectCompareVO.getChangeAfterNum() == null ? 0 : projectCompareVO.getChangeAfterNum()) + (groupCompare.getChangeAfterNum() == null ? 0 : groupCompare.getChangeAfterNum()));
					projectCompareVO.setChangeBeforeArea(priceVersionValueOrgServiceImpl.BigDecimalADD(projectCompareVO.getChangeBeforeArea(), groupCompare.getChangeBeforeArea()));
				}

				compareVOList.add(projectCompareVO);

			}
		}

		return compareVOList;
	}

	@Override
	public void updateNoticeStateByStageIdAndType(String projectFid, String noticeType, String noticeSource, String noticeState, String user, LocalDateTime now, Integer isDel) {
		sysNoticeMapper.updateNoticeStateByStageIdAndType(projectFid, noticeType, noticeSource, noticeState, user, now, isDel);
	}

	@Override
	public List<SysNotice> selectNoticeByProjectFidAndTaskType(String projectFid, List<String> noticeType, String versionType, String noticeState, int isDel) {
		return sysNoticeMapper.selectNoticeByProjectFidAndTaskType(projectFid, noticeType, versionType, noticeState, isDel);
	}

	@Override
	public List<SysNotice> selectNoticeByProcessMode(String projectFid, String noticeType, String versionType, String noticeState, int isDel) {
		return sysNoticeMapper.selectNoticeByProcessMode(projectFid, noticeType, versionType, noticeState, isDel);
	}

	@Override
	public List<SysNotice> selectNoticeByProcessingModeAndState() {
		return sysNoticeMapper.selectNoticeByProcessingModeAndState(ModuleTypeEunm.PRICE.getKey(), ProcessingModeEnum.MANUAL.getKey(), ProcessingStateEnum.UNTREATED.getKey(), IsDeleteEnum.NO.getKey());
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void noticeCheckSupplementPortalTodo() {
		List<SysNotice> sysNotices = selectNoticeByProcessingModeAndState();
		if (CollectionUtils.isNotEmpty(sysNotices)){
			for (SysNotice sysNotice : sysNotices){
				String instanceId = priceVersionValueOrgService.sendBackLog(sysNotice.getProjectId(), sysNotice.getStagesId(), sysNotice.getDescInfo(), null);
				if (StringUtils.isNotEmpty(instanceId)){
					sysNotice.setTaskName(sysNotice.getTaskName()+"("+ Constants.NOTICE_SUPPLEMENT_PORTALTODO+")");
					sysNotice.setPortalInstanceId(instanceId);
					sysNotice.setUpdateTime(LocalDateTime.now());
					updateById(sysNotice);
				}
			}
		}
	}

}
